/*
 * Copyright 2008 Max Kugland
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.splink.asbeangen.parser.utils;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import org.splink.asbeangen.parser.iface.Interfaze;

import com.wutka.dtd.DTDComment;

public class CommentMapper {
	public static String NEW_LINE = System.getProperty("line.separator");

	private List<String> _types = new ArrayList<String>();;
	private List<String> _generates = new ArrayList<String>();
	private List<String> _interfaces = new ArrayList<String>();

	public CommentMapper(Enumeration<?> items) {
		prepare(parseComments(items));
	}

	private List<DTDComment> parseComments(Enumeration<?> items) {
		List<DTDComment> comments = new ArrayList<DTDComment>();
		while (items.hasMoreElements()) {
			Object item = items.nextElement();
			if (item instanceof DTDComment)
				comments.add((DTDComment) item);
		}
		return comments;
	}

	private void prepare(List<DTDComment> comments) {
		for (int i = 0; i < comments.size(); i++) {
			String[] comment = comments.get(i).text.split(NEW_LINE);
			for (int j = 0; j < comment.length; j++) {
				String com = comment[j];
				if (com.indexOf("TYPE") != -1)
					_types.add(com.replace("TYPE", ""));
				else if (com.indexOf("GENERATE") != -1)
					_generates.add(com);
				else if (com.indexOf("INTERFACE") != -1)
					_interfaces.add(com.replace("INTERFACE", ""));
			}
		}
	}

	public List<Interfaze> getInterfaces() {
		List<Interfaze> v = new ArrayList<Interfaze>();
		for (int i = 0; i < _interfaces.size(); i++) {
			String iFace = _interfaces.get(i);
			String[] line = iFace.split(":");
			String[] implementors = line[1].split(",");

			v.add(new Interfaze(line[0].trim(), implementors));
		}
		return v;
	}

	public List<String> getInterfacesForClass(String classname) {
		List<String> v = new ArrayList<String>();
		for (int i = 0; i < _interfaces.size(); i++) {
			String iFace = _interfaces.get(i);
			if (iFace.indexOf(classname) != -1) {
				String[] line = iFace.split(":");
				String iFaceName = line[0].trim();
				String[] implementors = line[1].split(",");

				for (int j = 0; j < implementors.length; j++) {
					if (implementors[j].equals(classname)) {
						v.add(iFaceName);
					}
				}
			}
		}
		return v;
	}

	public List<String> getGenerate(String name) {
		List<String> v = new ArrayList<String>();
		for (int i = 0; i < _generates.size(); i++) {
			String statement = _generates.get(i).split("GENERATE")[1].trim();
			String node = statement.split("\\.")[0];
			String attribute = statement.split("\\.")[1];

			if (node.equals(name))
				v.add(attribute);
		}
		return v;
	}

	public String getCustomType(String type, String cardinal) {
		if (cardinal.equals("+") || cardinal.equals("*"))
			return "Array";
		return type;
	}

	public String getNativeType(String fullpath, String cardinal) {
		if (cardinal.equals("+") || cardinal.equals("*"))
			return "Array";

		String type = "Object";
		for (int i = 0; i < _types.size(); i++) {
			String[] comment = _types.get(i).split("=");
			String path = comment[0];

			if (fullpath.indexOf(fullpath) != -1) {
				String[] pathtokens = path.split("\\.");
				String[] fullpathtokens = fullpath.split("\\.");

				int equitycounter = 0;
				int j = pathtokens.length;
				while (--j >= 0) {
					if (fullpathtokens[j].trim().equalsIgnoreCase(pathtokens[j].trim()))
						equitycounter++;
				}
				if (equitycounter == pathtokens.length)
					type = comment[1];
			}
		}
		return type;
	}
}